Skip to content

GLM: fix KDA and router thread limits on M1 - #708

Merged
ashhart merged 1 commit into
ashhart:mainfrom
mrv777:fix/glm-kda-router-m1
Oct 16, 2026
Merged

ashhart merged 1 commit into
ashhart:mainfrom
mrv777:fix/glm-kda-router-m1

Conversation

@mrv777

@mrv777 mrv777 commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

On M1 Max, the two KDA pipelines compile for 512 threads, while several router specializations also fall below their 1,024-thread dispatch. These launches can leave outputs unwritten without a command-buffer error.

Reserve 1,024 threads in the generator and regenerate both KDA kernels and the router. Arithmetic, reduction order and dispatch sizes stay unchanged. Regressions check all 16 router row counts, both KDA head counts, output/state/cache coverage and recurrent window boundaries.

Rebased onto 1.0.10 at f930fbb7. #704 is merged; this branch now contains only the KDA/router commit.

Validated on M1 Max with Zig 0.17.0 (-Dcpu=apple_m1):

  • All three regressions pass; removing each annotation makes its corresponding test fail at the capacity assertion.
  • Router matches FP64 exactly; KDA passes FP64 bounds and matches the legal 512-thread control. The complete GLM rows check passes 1,328,072 values and 8,909,088 bit-equal comparisons.
  • Native build and goldens pass: 309/319 exact, ten declared differences, zero unexpected differences.
  • Full suite: 1,956 passed, eight skipped. The command still fails on the same checkpoint logging diagnostic as baseline; no new diagnostics. The previously known sparse-attention failure is fixed upstream.
  • All 34 Metal sources regenerate exactly; the index whitespace mismatch is inherited. Changed-file formatting passes; zero new lean findings (527 inherited).

API Validation passes; both KDA tests also pass Shader Validation. The router’s unchanged instrumented memory exceeds M1’s 32 KiB limit in some variants. Full-model inference, two-Mac TP2 and other GPUs remain untested. Raw logs remain local.

@mrv777
mrv777 force-pushed the fix/glm-kda-router-m1 branch from 434a62f to 588b02c Compare October 14, 2026 13:20
@mrv777
mrv777 marked this pull request as ready for review October 14, 2026 13:21
@ashhart
ashhart merged commit 51033be into ashhart:main Oct 16, 2026
3 of 4 checks passed
ashhart added a commit that referenced this pull request Oct 16, 2026
ashhart added a commit that referenced this pull request Oct 16, 2026
ashhart added a commit that referenced this pull request Oct 16, 2026
Decode launches hc_expand_10 at 1,024 threads a group at every step's last block boundary, and compiled offline for M1
and M2 the kernel built for 928. Its spec in tools/zig/gen_glm_kernels.py gains threads=1024, as #708 gave KDA and the
router; regenerated from the Python kernels it came from, only hc_expand_10.metal changes, by its
[[max_total_threads_per_threadgroup(1024)]] line, and offline it now builds for 1,024 on M1 and M2. The arithmetic is
unchanged. launch_check.zig runs it at 1, 5 and 16 rows against the exact values (dyadic inputs keep every fp32 step
exact, so the bf16 store is the one rounding) and checks the rows past the window and the unused outputs stay untouched.
The kernel contract records its launch, with the M1/M2 limit its compiles show.
@ashhart

ashhart commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Thank you, @mrv777. Asking the compiler for the 1,024 threads these kernels launch with is the fix, and the capacity assertions with the 512-thread control make the fault testable on any chip.

Your commit ships in TensorFold 1.0.12 under your name (8835f2b10). Our b4b6c9736 wraps four lines of launch_check.zig, and your head is merged after them with no change to the tree (51033befb), so this pull request shows as merged.

On an M3 Ultra all three launch_check tests pass. That chip's compiler already built these pipelines for 1,024 threads, so it cannot show the fault your M1 Max did; offline compiles for M1 and M2 can. Before your change both KDA pipelines compiled for 512 threads there and 13 of 16 router widths fell short; after it, every one compiles for 1,024. GLM-5.3-Flash with 8 of its 45 layers gave the same tokens as before, drafted and with "draft": false, in chats against a cache-off server and at 2 and 4 concurrent requests, with decode and cold prompts within 0.25%.

The same offline check showed hc_expand_10 built for 928 threads on M1 and M2, so db391f179 gives it the same request.

Posted by Ash's AI Assistant Synthena

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants